diff options
Diffstat (limited to 'src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx')
| -rw-r--r-- | src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx b/src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx new file mode 100644 index 0000000..6c91ba6 --- /dev/null +++ b/src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx @@ -0,0 +1,88 @@ +import { LoadingPanel } from '@/components/common/LoadingPanel'; +import { useDateRange, useMessages } from '@/components/hooks'; +import { useWebsiteStatsQuery } from '@/components/hooks/queries/useWebsiteStatsQuery'; +import { MetricCard } from '@/components/metrics/MetricCard'; +import { MetricsBar } from '@/components/metrics/MetricsBar'; +import { formatLongNumber, formatShortTime } from '@/lib/format'; + +export function WebsiteMetricsBar({ + websiteId, +}: { + websiteId: string; + showChange?: boolean; + compareMode?: boolean; +}) { + const { isAllTime } = useDateRange(); + const { formatMessage, labels, getErrorMessage } = useMessages(); + const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(websiteId); + + const { pageviews, visitors, visits, bounces, totaltime, comparison } = data || {}; + + const metrics = data + ? [ + { + value: visitors, + label: formatMessage(labels.visitors), + change: visitors - comparison.visitors, + formatValue: formatLongNumber, + }, + { + value: visits, + label: formatMessage(labels.visits), + change: visits - comparison.visits, + formatValue: formatLongNumber, + }, + { + value: pageviews, + label: formatMessage(labels.views), + change: pageviews - comparison.pageviews, + formatValue: formatLongNumber, + }, + { + label: formatMessage(labels.bounceRate), + value: (Math.min(visits, bounces) / visits) * 100, + prev: (Math.min(comparison.visits, comparison.bounces) / comparison.visits) * 100, + change: + (Math.min(visits, bounces) / visits) * 100 - + (Math.min(comparison.visits, comparison.bounces) / comparison.visits) * 100, + formatValue: n => `${Math.round(+n)}%`, + reverseColors: true, + }, + { + label: formatMessage(labels.visitDuration), + value: totaltime / visits, + prev: comparison.totaltime / comparison.visits, + change: totaltime / visits - comparison.totaltime / comparison.visits, + formatValue: n => + `${+n < 0 ? '-' : ''}${formatShortTime(Math.abs(~~n), ['m', 's'], ' ')}`, + }, + ] + : null; + + return ( + <LoadingPanel + data={metrics} + isLoading={isLoading} + isFetching={isFetching} + error={getErrorMessage(error)} + minHeight="136px" + > + <MetricsBar> + {metrics?.map(({ label, value, prev, change, formatValue, reverseColors }) => { + return ( + <MetricCard + key={label} + value={value} + previousValue={prev} + label={label} + change={change} + formatValue={formatValue} + reverseColors={reverseColors} + showChange={!isAllTime} + /> + ); + })} + </MetricsBar> + </LoadingPanel> + ); +} |